package v1alpha1

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type StraceChaosSpec struct {
	// ContainerSelector specifies the target for injection
	ContainerSelector `json:",inline"`

	// Duration represents the duration of the chaos
	// +optional
	Duration *string `json:"duration,omitempty"`

	Action StraceAction `json:"action"`

	// +optional
	// SyscallName 调用名，比如mmap
	SyscallName string `json:"syscallName"`
	// +optional
	// LatencyDuration 延迟时间
	LatencyDuration int `json:"latency"`
	// +optional
	// DelayLoc 取值范围enter或exit，表示执行前还是执行后注入延迟（为什么action=error的例子也设为了enter）
	DelayLoc string `json:"delayLoc"`
	// +optional
	// CgroupRoot cgroup根路径
	CgroupRoot string `json:"cgroupRoot"`
	// +optional
	// First 首次注入故障的调用是第几次
	First int `json:"first"`
	// +optional
	// Last 最后一次注入故障的调用是第几次
	Last int `json:"last"`
	// +optional
	// Step 故障注入间隔
	Step int `json:"step"`
	// +optional
	// Return 错误的返回值
	Return string `json:"return"`

	// RemoteCluster represents the remote cluster where the chaos will be deployed
	// +optional
	RemoteCluster string `json:"remoteCluster,omitempty"`
}

type StraceAction string

// latency, error
const (
	StraceActionLatency StraceAction = "latency"
	StraceActionError   StraceAction = "error"
)

// +kubebuilder:object:root=true
// +kubebuilder:printcolumn:name="action",type=string,JSONPath=`.spec.action`
// +kubebuilder:printcolumn:name="duration",type=string,JSONPath=`.spec.duration`
// +chaos-mesh:experiment

type StraceChaos struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   StraceChaosSpec            `json:"spec"`
	Status BladeOnlyCreateChaosStatus `json:"status,omitempty"`
}

var _ InnerObjectWithCustomStatus = (*StraceChaos)(nil)
var _ InnerObjectWithSelector = (*StraceChaos)(nil)
var _ InnerObject = (*StraceChaos)(nil)

func init() {
	SchemeBuilder.Register(&StraceChaos{}, &StraceChaosList{})
}

// GetSelectorSpecs is a getter for selectors
func (obj *StraceChaos) GetSelectorSpecs() map[string]interface{} {
	return map[string]interface{}{
		".": &obj.Spec.ContainerSelector,
	}
}

func (obj *StraceChaos) GetCustomStatus() interface{} {
	return &obj.Status.BladeOnlyCreateChaosCustomStatus
}
